package yggdrasil

import (
	"gitee.com/zawei/yggdrasil/pkg/cmd"
	"gitee.com/zawei/yggdrasil/pkg/config"
	cli2 "gitee.com/zawei/yggdrasil/pkg/config/source/cli"
	"gitee.com/zawei/yggdrasil/pkg/lib"
	"gitee.com/zawei/yggdrasil/pkg/metrics"
	"gitee.com/zawei/yggdrasil/pkg/transport/server"
	"gitee.com/zawei/yggdrasil/third_party/urfave/cli"
)

func loadCmdCfg(action func(ctx *cli.Context) error) func(ctx *cli.Context) error {
	return func(ctx *cli.Context) error {
		if err := config.Load(cli2.NewSource(cli2.Context(ctx))); err != nil {
			return err
		}
		return action(ctx)
	}
}

func initCmdCfg() {
	var initCmd func(cmds []*cli.Command)
	initCmd = func(cmds []*cli.Command) {
		for i, c := range cmds {
			if c.Action != nil {
				action := c.Action
				cmds[i].Action = loadCmdCfg(action)
			}
			if len(c.Subcommands) > 0 {
				initCmd(c.Subcommands)
			}
		}
	}
	initCmd(cmd.App().Commands)
	initCmd(cmd.GetOptions().Commands)
}

func initMetric() {
	metrics.InitRegistry()
	lib.Init()
	server.Init()
}

func Run() error {
	initMetric()
	initCmdCfg()
	return cmd.Run()
}
